def rlocus(name, sys, kvect, k=None): if k is None: k = kvect[-1] sysc = control.feedback(sys * k, 1) closed_loop_poles = control.pole(sysc) res = control.rlocus(sys, kvect, Plot=False) for locus in res[0].T: plt.plot(np.real(locus), np.imag(locus)) p = control.pole(sys) z = control.zero(sys) marker_props = { 'markeredgecolor': 'r', 'markerfacecolor': 'none', 'markeredgewidth': 2, 'markersize': 10, 'linestyle': 'none' } plt.plot(np.real(p), np.imag(p), marker='x', label='pole', **marker_props) plt.plot(np.real(z), np.imag(z), marker='o', label='zero', **marker_props) plt.plot(np.real(closed_loop_poles), np.imag(closed_loop_poles), marker='s', label='closed loop pole', **marker_props) plt.legend(loc='best') plt.xlabel('real') plt.ylabel('imag') plt.grid(True) plt.title(name + ' root locus')
def testAcker(self, fixedseed): for states in range(1, self.maxStates): for i in range(self.maxTries): # start with a random SS system and transform to TF then # back to SS, check that the matrices are the same. sys = rss(states, 1, 1) if (self.debug): print(sys) # Make sure the system is not degenerate Cmat = ctrb(sys.A, sys.B) if np.linalg.matrix_rank(Cmat) != states: if (self.debug): print(" skipping (not reachable or ill conditioned)") continue # Place the poles at random locations des = rss(states, 1, 1) poles = pole(des) # Now place the poles using acker K = acker(sys.A, sys.B, poles) new = ss(sys.A - sys.B * K, sys.B, sys.C, sys.D) placed = pole(new) # Debugging code # diff = np.sort(poles) - np.sort(placed) # if not all(diff < 0.001): # print("Found a problem:") # print(sys) # print("desired = ", poles) np.testing.assert_array_almost_equal(np.sort(poles), np.sort(placed), decimal=4)
def CaseB(sysg,wctar): para=50 R.ur = ((Spec.A + Spec.B) / Spec.e - 1) * 1.3 / G.DCgain R.sysR1 = ctrl.tf([R.ur], [1]) R.R2NUM=[(-ctrl.pole(G.sysG)[0]**-1)*(-ctrl.pole(G.sysG)[1]**-1), (-ctrl.pole(G.sysG)[0]**-1)+(-ctrl.pole(G.sysG)[1]**-1),1] R.R2DEN=[(-para*ctrl.pole(G.sysG)[0])**-2, 2*((-para*ctrl.pole(G.sysG)[0])**-1), 1] R.sysR2 = ctrl.tf(R.R2NUM, R.R2DEN) R.sysR = R.sysR1 * R.sysR2 return R.sysR
def locate_poles(): """ Finds location of a system's zeros and poles """ n1 = np.array([1, 1]) n2 = np.array([1, 2]) d1 = np.array([1, 2j]) d2 = np.array([1, -2j]) d3 = np.array([1, 3]) numerator_g, denominator_g = np.array([6, 0, 1]), np.array([1, 3, 3, 1]) sys_g = ct.tf(numerator_g, denominator_g) zeros_g = ct.zero(sys_g) pole_g = ct.pole(sys_g) numerator_h = np.convolve(n1, n2) denominator_h = np.convolve(d1, np.convolve(d2, d3)) sys_h = ct.tf(numerator_h, denominator_h) sys_tf = sys_g / sys_h pzmap_sys = ct.pzmap(sys_tf) print(AsciiTable([['Poles and Zeros']]).table) data = [['Function', 'Result Ouput'], ['G(s)', sys_g], ['Zeros(g)', zeros_g], ['Pole(g)', pole_g], ['H(s)', sys_h], ['T(s)', sys_tf], ['Pzmap(s)', pzmap_sys]] print(AsciiTable(data).table)
def initial_gamma(my_tf): """ Finds the initial gamma to use for the algorithm :param my_tf: :return: gamma: a singular value to use as our base case """ # We ultimately want to choose the greatest singular value of three, the first two are straightforward: sig_0 = abs(my_tf(0)) sig_inf = abs(my_tf(350)) # Now we want to choose a third value that is j*(our favorite pole) try: poles = tf.pole(my_tf) w = -np.inf if np.any(np.imag(poles)) != 0: for lamb in poles: lamby = abs((np.imag(lamb) / np.real(lamb)) * (1. / abs(lamb))) if lamby > w: w = abs(lamb) sig_w = abs(my_tf(w * 1.0j)) else: if np.all(np.real(poles)) == 0: # Case where all poles are 0 sig_w = abs(my_tf(0)) else: sig_w = np.min(abs(poles)) sig_w = abs(my_tf(sig_w * 1.0j)) except AssertionError: sig_w = -np.inf gamma = np.max([sig_0, sig_w, sig_inf]) return gamma
def get_poles_analyze(self): from control import pole poles = pole(self.w) print(poles) pole, zeros = pzmap(self.w) plt.title('Graph of poles') plt.plot() plt.show()
def plot_rlocus(self, fig): tf = self.tf if self.loop_type == 'ol' else self.tf_plant * self.tf_comp fig.clf() ax = fig.add_subplot(1, 1, 1) klist = np.linspace(500.0, 0, num=1000) rlist, _ = control.root_locus(tf, kvect=klist, Plot=False) rlist = np.vstack(rlist) poles = np.array(control.pole(tf)) ax.plot(np.real(poles), np.imag(poles), 'x') zeros = np.array(control.zero(tf)) if zeros.size > 0: ax.plot(np.real(zeros), np.imag(zeros), 'o') ax.plot(np.real(rlist), np.imag(rlist)) ax.axhline(0., linestyle=':', color='k', zorder=-20) ax.axvline(0., linestyle=':', color='k') ax.set_xlabel('Real axis') ax.set_ylabel('Imaginary axis') if not self.settings.is_rlocus_default(): zeta = self.settings.get_rlocus_zeta() wn = self.settings.get_rlocus_omega() x0 = -np.arccos(zeta) * wn if wn else ax.get_xlim()[0] xt = np.arange(x0, 0, 0.01) ax.plot(xt, -np.arccos(zeta) * xt, '--', linewidth=0.5, color='black') ax.plot(xt, np.arccos(zeta) * xt, '--', linewidth=0.5, color='black') x = np.arange(0, wn + 0.01, 0.01) y = np.sqrt(wn**2 - x**2) x = -np.concatenate([x, x[::-1]]) y = np.concatenate([y, -y[::-1]]) ax.plot(x, y, '--', linewidth=0.5, color='black') xmin = self.settings.get_rlocus_xmin() xmax = self.settings.get_rlocus_xmax() ymin = self.settings.get_rlocus_ymin() ymax = self.settings.get_rlocus_ymax() ax.set_xlim(xmin, xmax) ax.set_ylim(ymin, ymax) return fig
def CaseA(sysg,wctar): R.ur = ((Spec.A + Spec.B) / Spec.e - 1) * 1.3 / G.DCgain R.sysR1 = ctrl.tf([R.ur], [1]) tauAlow = ctrl.dcgain(G.sysG*R.sysR1) / (wctar*1.5) tauAhigh = sqrt(prod(-ctrl.pole(G.sysG*R.sysR1) ** -1) / tauAlow) R.R2NUM=G.DEN R.R2DEN=[tauAhigh * tauAhigh * tauAlow, 2 * tauAhigh * tauAlow, 2 * tauAhigh + tauAlow, 1] R.sysR2 = ctrl.tf(R.R2NUM,R.R2DEN ) R.sysR=R.sysR1*R.sysR2 return R.sysR
def draw_step_response_feedback(K,sys): # Defining feedback system C = control.tf(K,1) # Using feedback according to http://nl.mathworks.com/help/control/examples/using-feedback-to-close-feedback-loops.html controled_sys = control.feedback(C*sys,1) poles = control.pole(controled_sys) y,t = control.step(controled_sys) plt.plot(t,y) plt.xlabel('t') plt.ylabel('y(t)')
def TF_properties(self, window, key, entry1, entry2): transfer_function = self.get_TF(entry1, entry2) if key == "dcgain": dc_gain = co.dcgain(transfer_function) self.print_TF_props(window, dc_gain, "DC Gain:") elif key == "poles": poles = co.pole(transfer_function) self.print_TF_props(window, poles, "Poles:") elif key == "zeros": zeros = co.zero(transfer_function) self.print_TF_props(window, str(zeros), "Zeros:")
def compute_cl_poles(ctl_num, ctl_den): ctl_tf = control.tf(ctl_num, ctl_den, dt) #print(ctl_tf) cl_tf = control.feedback(dt_tf, ctl_tf, sign=-1) #print control.damp(cl_tf) #print(cl_tf) cl_poles_d = control.pole(cl_tf) #print(cl_polesd) cl_poles_c = np.sort_complex(np.log(cl_poles_d) / dt) print('cl_poles_c\n{}'.format(cl_poles_c)) return cl_poles_d
def time(tf): print "Poles: ", ctrl.pole(tf) print "Zeros: ", ctrl.zero(tf) dc = ctrl.dcgain(tf) print "DC gain: ", dc t, y = ctrl.step_response(tf) ys = filter(lambda l: l >= 0.98 * dc, y) i = np.ndarray.tolist(y).index(min(ys)) print "Ts: ", t[i] print "Overshoot: ", (max(y) / dc) - 1 i = np.ndarray.tolist(y).index(max(y)) print "Tr: ", t[i]
def test_poles(self, fun, args): sys = fun(*args) np.testing.assert_allclose(sys.poles(), 42) np.testing.assert_allclose(poles(sys), 42) with pytest.warns(PendingDeprecationWarning): pole_list = sys.pole() assert pole_list == sys.poles() with pytest.warns(PendingDeprecationWarning): pole_list = ct.pole(sys) assert pole_list == sys.poles()
def rootlocus(sys, kvect=None): if kvect is None: kvect = np.logspace(-3, 0, 1000) rlist, klist = control.rlocus(sys, plot=False, kvect=kvect) for root in rlist.T: plt.plot(np.real(root), np.imag(root)) plt.plot(np.real(root[-1]), np.imag(root[-1]), 'bs') for pole in control.pole(sys): plt.plot(np.real(pole), np.imag(pole), 'rx') for zero in control.zero(sys): plt.plot(np.real(zero), np.imag(zero), 'go') plt.grid() plt.xlabel('real') plt.ylabel('imag')
def question1(Gpr, plot=True): print(spacer + "Question 1" + spacer) # 1. POLES AND ZEROS poles = ct.pole(Gpr) zeros = ct.zero(Gpr) print("\t Poles of the system are {}, and zeroes are {}".format( poles, zeros)) # 2. PZ MAP H = 1 OLTF = Gpr * H plt.figure("Q1 - PZ map") ct.pzmap(OLTF) if plot: plt.show # 3. STABILITY stable = True for pole in poles: if (pole > 0): stable = False temp = "unstable" if (stable): temp = "stable" print("\t Since {} are the poles, the system is {}".format(poles, temp)) # 4. STEP RESPONSE t, c = ct.step_response(OLTF) end_value = c[c.size - 1] print("\t The end value of the OL step_response is {}".format(end_value)) plt.figure("Q1 - Step response") plt.plot(t, c) # plot asymptote x_coordinates = [t[0], t[t.size - 1]] y_coordinates = [end_value, end_value] plt.plot(x_coordinates, y_coordinates) if plot: plt.show() return OLTF
def draw_root_locus(self): co.root_locus(co.feedback(0.00001 * self.process * self.pid), Plot=True, grid=False) st = -self.sigma + self.wp * 1j poles_and_zeros = np.append(np.append(self.zeros, self.poles), [st, np.conj(st)]) ymin = np.min(np.imag(poles_and_zeros)) - 2 ymax = np.max(np.imag(poles_and_zeros)) + 2 xmin = np.min(np.real(poles_and_zeros)) - 2 xmax = np.max(np.real(poles_and_zeros)) + 2 plt.ylim(ymin, ymax) plt.xlim(xmin, xmax) for root in co.pole(self.closed_loop): plt.plot(np.real(root), np.imag(root), color='red', marker='*') plt.text(np.real(root) + 0.1, np.imag(root) + (ymax - ymin) / 20 * (1 if np.imag(root) > 0 else -1), f'{root:.2f}', color='red') x = np.real(st) y = np.imag(st) plt.fill_between([0, xmax * 1.1], ymin * 1.1, ymax * 1.1, color='red', alpha=0.1) plt.fill_between([xmin * 1.1, 0], ymax * 1.1, [-self.tan_phi * xmin * 1.1, 0], color='red', alpha=0.1) plt.fill_between([xmin * 1.1, 0], [self.tan_phi * xmin * 1.1, 0], ymin * 1.1, color='red', alpha=0.1) plt.fill_between([x, 0], [y, 0], [-y, 0], color='red', alpha=0.1) plt.grid() plt.show()
def info_step(self): for p in control.pole(self.tf): if np.real(p) > 0: return 'Unstable system' if self.settings.is_step_default(): t, y = control.step_response(self.tf) else: tmax = self.settings.get_step_time_max() step = self.settings.get_step_step() t = np.arange(0, tmax, step) _, y = control.step_response(self.tf, t) yf = y[-1] os = 100 * (abs(y.max() - yf) / yf) tp = t[np.where(y == y.max())][0] ts = 0 # Temporary fix for TF = 1 try: for i in range(-1, -len(t) + 1, -1): if y[i - 1] > 1.02 * yf or y[i - 1] < 0.98 * yf: ts = t[i] break except UnboundLocalError: pass tr_max = t[np.where(y > 0.9 * yf)][0] tr_min = t[np.where(y > 0.1 * yf)][0] tr = tr_max - tr_min res = 'OS : {:.2f}% | Tp : {:.2f}s | Ts : {:.2f}s | Tr : {:.2f}s '.format( os, tp, ts, tr) return res
def loop_analysis(name, sys, zeta, wd, k, t_vect, k_vect, omega_vect): sysc = control.feedback(sys * k, 1) closed_loop_poles = control.pole(sysc) plt.figure(figsize=(10, 5)) rlocus(name, sys, k_vect, k) plt.axis([-16, 0, -8, 8]) theta = np.arccos(zeta) plt.plot([0, -10], [0, 10 * np.tan(theta)], 'r--') plt.vlines(-wd, -8, 8, linestyle='--', color='r') plt.figure(figsize=(10, 5)) bode(name, sys, omega_vect, margins=True) plt.figure(figsize=(10, 5)) control.nyquist(sys, omega=omega_vect) plt.title(name + ' nyquist') plt.axis([-10, 10, -10, 10]) plt.figure(figsize=(10, 5)) step_reponse(name, sysc, t_vect) plt.figure(figsize=(10, 5)) bode(name + ' closed loop ', sysc, np.logspace(-2, 2))
def time (tf, method = 'step', plot = False): print "=================================================================="; print "Poles: ", ctrl.pole (tf); print "Zeros: ", ctrl.zero (tf); dc = ctrl.dcgain (tf); print "DC gain: ", dc; if (method == 'step'): t, y = ctrl.step_response (tf); if (method == 'impulse'): t, y = ctrl.impulse_response (tf); ys = filter (lambda l: l >= 0.98 * dc, y); i = np.ndarray.tolist(y).index (min (ys)); print "Ts: ", t[i]; print "Overshoot: ", (max (y) / dc) - 1; i = np.ndarray.tolist(y).index (max (y)); print "Tr: ", t[i]; if (plot == True): p = Plotter ({'grid' : True}); p.plot ([(t, y)]); return t, y
def CaseC(sysg,wctar): PoleCanN=2 if PoleCanN == 0: R.R2NUM = [1] R.R2DEN = [1] elif PoleCanN == 1: R.R2NUM = [-ctrl.pole(G.sysG)[2] ** -1, 1] R.R2DEN = [1] elif PoleCanN == 2: R.R2NUM = [(-ctrl.pole(G.sysG)[1] ** -1) * (-ctrl.pole(G.sysG)[2] ** -1), (-ctrl.pole(G.sysG)[1] ** -1) + (-ctrl.pole(G.sysG)[2] ** -1), 1] R.R2DEN = [-ctrl.pole(G.sysG)[0] ** -1, 1] R.sysR1 = ctrl.tf([R.ur], [1, 0]) R.sysR2 = ctrl.tf(R.R2NUM, R.R2DEN) R.sysR = R.sysR1 * R.sysR2 return R.sysR
s = co.tf('s') a = 1 / (s - 3) b = (s + 2) / (s - 2) c = (s + 3) / (s + 4) e = 1 / (s * ((s**2) + 1)) acp = co.parallel(c, a) bap = co.parallel(b, a) acbas = co.series(acp, bap) acbaef = co.feedback(acbas, e, +1) print(acbaef) g_poles = co.pole(acbaef) print("G poles") for elem in g_poles: print(f'{elem: .2f}') g_zeros = co.zero(acbaef) print("G zeros") for elem in g_zeros: print(f'{elem: .2f}') g1_map = co.pzmap(acbaef, plot=True) t = np.linspace(0, 25, 100) t1, stp = co.step_response(acbaef, t) t2, imp = co.impulse_response(acbaef, t) # Warning for infinite impulse at t=0
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Wed Nov 27 00:49:43 2019 Todos estos códigos requieren comentarios y una limpieza Limpio=NO Comentarios=NO @author: carlos """ import control as ct import sympy as sym import numpy as np import matplotlib.pyplot as plt from scipy import signal from matplotlib.ticker import (MultipleLocator) Gp = ct.tf(100, [1, 0, 100]) ts = 0.05 Gz = ct.sample_system(Gp, ts) sym.pprint(Gz) """ apartado b) """ polos = ct.pole(Gz) magnitudpolos = abs(polos) sym.pprint(magnitudpolos)
B = np.array([[0, 0], [2 * Ca / m, 0], [0, 0], [2 * Ca * Lf / Iz, 0]]) C = np.eye(4) D = np.zeros((4, 2)) AB = np.matmul(A, B) A2B = np.matmul(A, AB) A3B = np.matmul(A, A2B) P = np.concatenate((B, AB), axis=1) P = np.concatenate((P, A2B), axis=1) P = np.concatenate((P, A3B), axis=1) U, sigma, V = np.linalg.svd(P) sigDivide[index] = sigma[0] / sigma[3] sys = control.StateSpace(A, B, C, D) pole1[index] = control.pole(sys)[0] pole2[index] = control.pole(sys)[1] pole3[index] = control.pole(sys)[2] pole4[index] = control.pole(sys)[3] index += 1 # print(sigDivide) plt.figure() plt.title("Log10(Largest Sigma / Smallest Sigma) vs Vx") plt.plot(Vx, sigDivide) plt.xlabel("Vx [m/s]") plt.ylabel("log10(sig1/sign)") plt.grid() plt.savefig("P2_Q1_a", bbox_inches='tight') plt.show()
import control as co import matplotlib.pyplot as plt import numpy as np s = co.tf('s') g1 = (s + 1) / ((s**2) - (3 * s) + 2) h1 = co.feedback(g1, 2, -1) h2 = co.feedback(g1, 3, -1) h3 = co.feedback(g1, 5, -1) print("poles (k=2)") for elem in co.pole(h1): print(f'{elem: .2f}') print("poles (k=3)") for elem in co.pole(h2): print(f'{elem: .2f}') print("poles (k=5)") for elem in co.pole(h3): print(f'{elem: .2f}') plt.figure(1) h1_map = co.pzmap(h1, plot=True, title='pzmap (k=2)') plt.figure(2) h2_map = co.pzmap(h2, plot=True, title='pzmap (k=3)') plt.figure(3) h3_map = co.pzmap(h3, plot=True, title='pzmap (k=5)') t = np.linspace(0, 10, 1000) t1, imp1 = co.impulse_response(h1, t)
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Thu Nov 28 14:37:18 2019 Todos estos códigos requieren comentarios y una limpieza Limpio=NO Comentarios=NO @author: carlos """ import control as ct import sympy as sym import numpy as np import matplotlib.pyplot as plt from scipy import signal from matplotlib.ticker import (MultipleLocator) T = ct.tf([1, 1, 0], [1, 0.1, -0.2]) polos = ct.pole(T) print(abs(polos))
def plot_ts(TS): plt.axvline(-4 / TS, color='r', linestyle='--') s = co.tf('s') g = (s + 1) / ((s - 1) * (s - 4)) h1 = 1 h2 = 1 / (s - 1) #b) k = 60 gf = co.feedback( k * pd_comp(-4.4) * g, h2, -1 ) # υπολογίζω τους πόλου και τα μηδενικά του κλειστού συστήματος με Κ = 60 και feedback=h2 poles = co.pole(gf) zeros = co.zero(gf) print(f"poles: {poles}") print(f"zeros: {zeros}") plt.figure(1) co.root_locus( pd_comp(-4.4) * g * h2, grid=False) # σχεδιάζω την γραφική παράστασή μου με pd_compensator plot_ts(2) plt.xlim(-15, 5) plt.plot(poles.real, poles.imag, 'rx') t = np.linspace(0, 3, 1000) t1, yout = co.step_response(gf, t)
numG = np.array([25]) denG = np.array([1, 5, 0]) Ls = ctl.tf(numG, denG) print("L(s) = ", Ls) # malha de realimentação numH = np.array([1]) denH = np.array([1]) Hs = ctl.tf(numH, denH) print("H(s) = ", Hs) # Função de transferência de malha fechada Ts = ctl.feedback(ctl.series(Ls, 1), Hs, sign=-1) print("Função de transferência do sistema em malha fechada", Ts) print("Zeros: ", ctl.zero(Ts)) print("Polos: ", ctl.pole(Ts)) # Calculo da Resposta ao degrau Tsim = 3 T, yout = ctl.step_response(Ts, Tsim) infomation = ctl.step_info(Ts) print("Informações: ", infomation) # Calcular o degrau unitário T2 = np.linspace(-1, Tsim, 1000) degrau = np.ones_like(T2) degrau[T2 < 0] = 0 #plotar os resultados plt.plot(T, yout, 'k-') plt.plot(T2, degrau, 'r-')
print(alfa,beta) def Controller(k): global alfa,beta N = [k,k*alfa,k*beta] D = [1,0] C = ctl.tf(N,D) zeros = np.roots(N) poles = np.roots(D) return C,zeros,poles ##DEFINE THE PLANT G = ctl.tf([1],[L*((M+m)-m),0,-(M+m)*g]) ##PLOT POLES AND ZEROS OF PLANT AND CONTROLLER open_poles = ctl.pole(G) open_zeros = ctl.zero(G) plt.plot(np.real(open_poles),np.imag(open_poles),'gx',label='Plant Open Loop Poles',markersize=15) plt.plot(np.real(open_zeros),np.imag(open_zeros),'go',label='Plant Zeros',markersize=10) C,zeros,poles = Controller(1) plt.plot(np.real(zeros),np.imag(zeros),'ro',label='Control Zeros',markersize=10) plt.plot(np.real(poles),np.imag(poles),'rx',label='Control Poles',markersize=15) ###LOOP ON K TO MAKE LOCUS k_vec = np.linspace(0,1000,1000) for k in k_vec: #print(k) C,zeros,poles = Controller(k) GCL = C*G/(1+C*G) poles = ctl.pole(GCL) plt.plot(np.real(poles),np.imag(poles),'b*')
import control import numpy import matplotlib.pyplot as plot def system(): """ This function calculates the transferfunction of series cirucit of Resistance R1 with capacity C1 and C2 || R2. Aswell the system. state representation. """ R1 = 20e3 C1 = 15e-9 C2 = 560e-12 R2 = 10e3 T1 = 1 / (R1 * C1) T2 = 1 / (R2 * C2) T3 = 1 / (R1 * C2) numerator_out = [T1, 0] dominator_out = [1, (T1 + T2 + T3), T1 * T2] return numerator_out, dominator_out omega = numpy.arange(0, 10e3, 50) system = control.tf(system()[0], system()[1]) control.bode_plot(system, dB=True) print(control.pole(system)) plot.show()
import control as co import numpy as np import matplotlib.pyplot as plt G1 = co.tf([2,5],[1,2,3]) # 2s + 5 / s^2 + 2s + 3 --- Provided only the coeficients G2 = 5*co.tf(np.poly([-2,-5]), np.poly([-4,-5,-9])) # Provided the 'zeros' and the 'poles' of the function # Algebrism is supported G3 = G1+G2 G4 = G1*G2 G5 = G1/G2 G6 = G1-G2 G7 = co.feedback(G1,G2) # Minimum Realization (Pole-Zero Cancellation) co.minreal(G2) # TF Properties print(G1) print('DC Gain: '+ str(co.dcgain(G1))) # DC Gain print('Pole: ' + str(co.pole(G1))) # Pole for G6 print('Zero: ' + str(co.zero(G1))) # Zero for G6
L2 = 4.0 # [m] # Zustandsraummodell A = np.matrix([[0, 0], [V / L2, -V / L2]]) B = np.matrix([[V / L1], [0]]) C = np.matrix([[0, 1]]) D = np.matrix([[0]]) # Zustandsraummodell erstellen mit "ss" ss_fwd = control.ss(A, B, C, D) # Pole berechnen pole_fwd = control.pole(ss_fwd) print(pole_fwd) # Eigenvektoren berechnen --> Grenzstabil U, V = np.linalg.eig(A) print(U, V) # Rückwärtsfahren V = -5 # [m/s] A = np.matrix([[0, 0], [V / L2, -V / L2]]) B = np.matrix([[V / L1], [0]]) # Zustandsraummodell erstellen mit "ss" ss_bwd = control.ss(A, B, C, D) # Pole berechnen pole_bwd = control.pole(ss_bwd)