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 test_plot(sys): fig = plt.figure(facecolor='w') mag, phase, omega = matlab.bode(sys) fig = plt.figure(facecolor='w') real, imag, freq = matlab.nyquist(sys) fig = plt.figure(facecolor='w') matlab.nichols(sys) rlist, klist = matlab.rlocus(sys, klist=None) # fig = plt.figure(facecolor = 'w') # #对数幅相特性曲线 # ax = fig.add_subplot(221) # ax.grid(True) ## real = mag*np.sin(phase) ## imag = mag*np.cos(phase) # plt.plot(real, imag) # ax = fig.add_subplot(223) # ax.grid(True) # real = np.log(mag)*np.sin(phase) # imag = np.log(mag)*np.cos(phase) # plt.plot(real, imag) # #对数频率特性曲线 # ax = fig.add_subplot(222) # ax.grid(True) # plt.plot(np.log(omega), np.log(mag)) # ax = fig.add_subplot(224) # ax.grid(True) # plt.plot(np.log(omega), phase) plt.show()
def dampingRatioFromGain(transferFunction, gain) : data = matlab.rlocus(tf, array([gain])) for j in range(0, len(data[0][0])): for i in range(0, len(data[0])) : data_point = data[0][i][j] if data_point.imag > 0 : print "Damping Ratio : ", sin(atan(abs(-1*data_point.real / data_point.imag)))
def valuesFromDampingRatio(transferFunction, dampingRatio): minGainSample = 0 spacing = 1000 closerToMGS = False gainFound = False slopeOfDampingRatioLine = abs(tan(arcsin(dampingRatio))) while not gainFound : data = matlab.rlocus(tf, array([minGainSample,minGainSample + (spacing),minGainSample + (2*spacing), minGainSample + (3*spacing),minGainSample + (4*spacing),minGainSample + (5*spacing), minGainSample + (6*spacing),minGainSample + (7*spacing),minGainSample + (8*spacing), minGainSample + (9*spacing),minGainSample + (10*spacing)])) for j in range(0, len(data[0][0])): for i in range(1, len(data[0])) : data_point = data[0][i][j] if data_point.imag > 0 : if (data[0][i-1][j].imag > 0 and abs(-1*data_point.real / data_point.imag) <= slopeOfDampingRatioLine and abs(-1*data[0][i-1][j].real / data[0][i-1][j].imag) >= slopeOfDampingRatioLine) : minGainSample = data[1][i-1] if(data[0][i-1][j].imag > 0 and abs(abs(-1*data_point.real / data_point.imag) - abs(slopeOfDampingRatioLine)) >= abs(abs(-1*data[0][i-1][j].real / data[0][i-1][j].imag) - abs(slopeOfDampingRatioLine))) : closerToMGS = True else : closerToMGS = False if spacing == 0.1: gainFound = True else : spacing = spacing / 10 if closerToMGS : print "Gain : ", minGainSample else : print "Gain : ", minGainSample + 0.1
def dampingRatioFromGain(transferFunction, gain): data = matlab.rlocus(tf, array([gain])) for j in range(0, len(data[0][0])): for i in range(0, len(data[0])): data_point = data[0][i][j] if data_point.imag > 0: print "Damping Ratio : ", sin( atan(abs(-1 * data_point.real / data_point.imag)))
def gainFromDampingRatio(transferFunction, dampingRatio): """ Returns gain found from a given control.matlab.tf transferFunction and dampingRatio By sampling along matlab.rlocus plot. Converges on an area of the plot by taking smaller sized samples (defined by variable 'spacing') in each iteration until spacing = 0.1 , thus the gain will only ever be within 0.1 """ minGainSample = 0.0 spacing = 1000.0 closerToMGS = False gainFound = False slopeOfDampingRatioLine = abs(sympy.tan(sympy.asin(dampingRatio))) while not gainFound: data = matlab.rlocus( transferFunction, np.array([ minGainSample, minGainSample + (1.0 * spacing), minGainSample + (2.0 * spacing), minGainSample + (3.0 * spacing), minGainSample + (4.0 * spacing), minGainSample + (5.0 * spacing), minGainSample + (6.0 * spacing), minGainSample + (7.0 * spacing), minGainSample + (8.0 * spacing), minGainSample + (9.0 * spacing), minGainSample + (10.0 * spacing) ])) for j in range(0, len(data[0][0])): for i in range(1, len(data[0])): data_point = data[0][i][j] if data_point.imag > 0: if (data[0][i - 1][j].imag > 0 and abs(data_point.real / data_point.imag) <= slopeOfDampingRatioLine and abs(data[0][i - 1][j].real / data[0][i - 1][j].imag) >= slopeOfDampingRatioLine): minGainSample = data[1][i - 1] if (data[0][i - 1][j].imag > 0 and abs( abs(data_point.real / data_point.imag) - abs(slopeOfDampingRatioLine)) >= abs( abs(data[0][i - 1][j].real / data[0][i - 1][j].imag) - abs(slopeOfDampingRatioLine))): closerToMGS = True else: closerToMGS = False if spacing == 0.1: gainFound = True else: spacing = spacing / 10 ## End While Loop if closerToMGS: return minGainSample else: return minGainSample + 0.1
def overshootFromGain(transferFunction, gain) : data = matlab.rlocus(tf, array([gain])) dampingRatio = 0 for j in range(0, len(data[0][0])): for i in range(0, len(data[0])) : data_point = data[0][i][j] if data_point.imag > 0 : dampingRatio = sin(atan(abs(-1*data_point.real / data_point.imag))) exponent = -1*dampingRatio*( pi/sqrt(1 - dampingRatio**2)) overshoot = 100*exp(exponent) print "Overshoot : ", overshoot
def overshootFromGain(transferFunction, gain): data = matlab.rlocus(tf, array([gain])) dampingRatio = 0 for j in range(0, len(data[0][0])): for i in range(0, len(data[0])): data_point = data[0][i][j] if data_point.imag > 0: dampingRatio = sin( atan(abs(-1 * data_point.real / data_point.imag))) exponent = -1 * dampingRatio * (pi / sqrt(1 - dampingRatio**2)) overshoot = 100 * exp(exponent) print "Overshoot : ", overshoot
def dampingRatioFromGain(transferFunction, gain): """ Finds and returns DampingRatio given a control.matlab.tf transferFunction and gain """ data = matlab.rlocus(transferFunction, np.array([gain])) damping_ratio = 0 for j in range(0, len(data[0][0])): for i in range(0, len(data[0])): data_point = data[0][i][j] if data_point.imag > 0: return np.sin(np.arctan(abs(-1*data_point.real / data_point.imag))) return damping_ratio
def frequencyFromGain(transferFunction, gain): """ Returns frequency from given control.matlab.tf transferFunction and gain. frequency was observed to equal to the distance from origin to a point on the control.matlab.rlocus plot. """ data = matlab.rlocus(transferFunction, np.array([gain])) frequency = 0 for j in range(0, len(data[0][0])): for i in range(0, len(data[0])): data_point = data[0][i][j] if data_point.imag > 0: return np.sqrt(data_point.real**2 + data_point.imag**2) return frequency
def valuesFromDampingRatio(transferFunction, dampingRatio): minGainSample = 0 spacing = 1000 closerToMGS = False gainFound = False slopeOfDampingRatioLine = abs(tan(arcsin(dampingRatio))) while not gainFound: data = matlab.rlocus( tf, array([ minGainSample, minGainSample + (spacing), minGainSample + (2 * spacing), minGainSample + (3 * spacing), minGainSample + (4 * spacing), minGainSample + (5 * spacing), minGainSample + (6 * spacing), minGainSample + (7 * spacing), minGainSample + (8 * spacing), minGainSample + (9 * spacing), minGainSample + (10 * spacing) ])) for j in range(0, len(data[0][0])): for i in range(1, len(data[0])): data_point = data[0][i][j] if data_point.imag > 0: if (data[0][i - 1][j].imag > 0 and abs(-1 * data_point.real / data_point.imag) <= slopeOfDampingRatioLine and abs(-1 * data[0][i - 1][j].real / data[0][i - 1][j].imag) >= slopeOfDampingRatioLine): minGainSample = data[1][i - 1] if (data[0][i - 1][j].imag > 0 and abs( abs(-1 * data_point.real / data_point.imag) - abs(slopeOfDampingRatioLine)) >= abs( abs(-1 * data[0][i - 1][j].real / data[0][i - 1][j].imag) - abs(slopeOfDampingRatioLine))): closerToMGS = True else: closerToMGS = False if spacing == 0.1: gainFound = True else: spacing = spacing / 10 if closerToMGS: print "Gain : ", minGainSample else: print "Gain : ", minGainSample + 0.1
def overshootFromGain(transferFunction, gain): """ Finds overshoot of control.matlab.tf transferFunction given gain. """ data = matlab.rlocus(transferFunction, np.array([gain])) dampingRatio = 0.0 overshoot = 0.0 for j in range(0, len(data[0][0])): for i in range(0, len(data[0])): data_point = data[0][i][j] if data_point.imag > 0 : dampingRatio = np.sin(np.arctan(abs(data_point.real / data_point.imag))) if abs(1-dampingRatio**2) > 0: exponent = -1*dampingRatio*( np.pi/np.sqrt(1 - dampingRatio**2)) overshoot = 100*np.exp(exponent) return overshoot
def gainFromDampingRatio(transferFunction, dampingRatio): """ Returns gain found from a given control.matlab.tf transferFunction and dampingRatio By sampling along matlab.rlocus plot. Converges on an area of the plot by taking smaller sized samples (defined by variable 'spacing') in each iteration until spacing = 0.1 , thus the gain will only ever be within 0.1 """ minGainSample = 0.0 spacing = 1000.0 closerToMGS = False gainFound = False slopeOfDampingRatioLine = abs(sympy.tan(sympy.asin(dampingRatio))) while not gainFound : data = matlab.rlocus(transferFunction, np.array([minGainSample,minGainSample + (1.0*spacing),minGainSample + (2.0*spacing), minGainSample + (3.0*spacing),minGainSample + (4.0*spacing),minGainSample + (5.0*spacing), minGainSample + (6.0*spacing),minGainSample + (7.0*spacing),minGainSample + (8.0*spacing), minGainSample + (9.0*spacing),minGainSample + (10.0*spacing)])) for j in range(0, len(data[0][0])): for i in range(1, len(data[0])) : data_point = data[0][i][j] if data_point.imag > 0 : if (data[0][i-1][j].imag > 0 and abs(data_point.real / data_point.imag) <= slopeOfDampingRatioLine and abs(data[0][i-1][j].real / data[0][i-1][j].imag) >= slopeOfDampingRatioLine) : minGainSample = data[1][i-1] if(data[0][i-1][j].imag > 0 and abs(abs(data_point.real / data_point.imag) - abs(slopeOfDampingRatioLine)) >= abs(abs(data[0][i-1][j].real / data[0][i-1][j].imag) - abs(slopeOfDampingRatioLine))) : closerToMGS = True else : closerToMGS = False if spacing == 0.1: gainFound = True else : spacing = spacing / 10 ## End While Loop if closerToMGS : return minGainSample else : return minGainSample + 0.1
def testRlocus_list(self, siso, mplcleanup): """Test rlocus() with list""" klist = [1, 10, 100] rlist, klist_out = rlocus(siso.tf2, klist, plot=False) np.testing.assert_equal(len(rlist), len(klist)) np.testing.assert_allclose(klist, klist_out)
def testRlocus(self, siso, subsys, mplcleanup): """Call rlocus()""" rlocus(getattr(siso, subsys))
# x_s = -2.5 # real # y_s = 2 # complexo # teta = np.arctan(np.abs(y_s)/np.abs(x_s)) # eps = np.cos(teta) ################################################################################ # polos e zeros plotados ################################################################################ (p, z) = ctl.pzmap(G) print('polos =', p) print('zeros =', z) ################################################################################ # Lugar geometrico das raizes (LGR) ################################################################################ rlist, klist = ctl.rlocus(G) # rlist - lugar geometrico das raizes # klist - ganhos correspondentes # plotar linha baseada no LGR para achar interseção real = [] im = [] try: for j in range(len(rlist)): real.append(rlist[j][ramo].real) im.append(rlist[j][ramo].imag) plt.plot(real, im, 'b-') except: pass ################################################################################
import control.matlab as ctl import matplotlib.pyplot as plt import numpy as np num = np.array([1, 1]) den = np.array([3, 9, 0, 0]) GH = ctl.tf(num, den) print(GH) print("Zeros: ", ctl.zero(GH)) print("Plos: ", ctl.pole(GH)) rlist, klist = ctl.rlocus(GH, PrintGain=True, grid=True) plt.grid() print(plt.show())
plt.axhline(1, color="b", linestyle="--") plt.xlim(0, 3) plt.show() # impulse response yout, T = matlab.impulse(sys, t) plt.plot(T, yout) plt.axhline(0, color="b", linestyle="--") plt.xlim(0, 3) #plt.show() # nyquist diagram matlab.nyquist(sys) #plt.show() # bode diagram matlab.bode(sys) #plt.show() # root locus matlab.rlocus(sys) #plt.show() # pole matlab.pole(sys) #plt.show() # margin matlab.margin(sys) #plt.show()
def rlocfind2(num, den, desired_zeta): ''' Find the locations on the root locus with the closest damping values Computes numerically, a bit hacky 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 desired_zeta: [float] desired damping coefficient value Returns: :return: polelocs: [array-like] complex valued pole locations that meet requested zeta values :return: ks: [array-like] gain at selected pole locations on root locus :return: wnvals: [array-like] natural frequency at selected pole locations :return: zvals: [array-like] actual damping value and selected pole locations ''' rlist, klist = rlocus(tf(num, den)) anglelist = angle(rlist) tem = shape(anglelist) tem = tem[1] zlist = ones(shape(rlist)) for k in range(tem): for j in range(len(klist)): zlist[j, k] = abs(cos(anglelist[j, k])) locclosest = ones(tem) eps = ones(tem) for k in range(tem): difflist = ones(len(klist)) for j in range(len(klist)): difflist[j] = abs(desired_zeta - zlist[j, k]) # minv = min(difflist[0:len(difflist)]) for j in range(len(klist)): if difflist[j + 1] <= difflist[j]: locclosest[k] = j + 1 eps[k] = difflist[j + 1] elif difflist[j + 1] > difflist[j]: break locclosest = ndarray.tolist(locclosest) for k in range(len(locclosest)): locclosest[k] = int(locclosest[k]) locs = ones((tem, 3)) for k in range(tem): locs[k, :] = [ real(rlist[locclosest[k], k]), imag(rlist[locclosest[k], k]), klist[locclosest[k]] ] polelocs = locs[:, 0] + locs[:, 1] * 1j ks = locs[:, 2] validvals = zeros((tem, 1)) for k in range(len(eps)): if eps[k] < 0.1: validvals[k] = 1 inc = 0 finallocs = ndarray.tolist(zeros(int(sum(validvals)))) finalks = zeros(int(sum(validvals))) for k in range(len(eps)): if validvals[k] == 1.: finallocs[inc] = polelocs[k] finalks[inc] = ks[k] inc = inc + 1 ks = finalks polelocs = finallocs wnvals = sqrt(real(polelocs)**2 + imag(polelocs)**2) zvals = angle(polelocs) for k in range(len(zvals)): zvals[k] = abs(cos(zvals[k])) return polelocs, ks, wnvals, zvals