def rga_plot(G, axlim=None, w_start=-2, w_end=2, points=100): ''' Plots the relative gain interaction between each output and input pairing Parameters ---------- G : numpy array plant model Returns ------- fig(RGA) : figure A figure of subplots for each interaction between an output and an input. Example ------- # Adapted from example 3.11 pg 86 S. Skogestad >>> def G(s): ... G = 0.01*numpy.exp(-5*s)/((s + 1.72e-4)*(4.32*s + 1))*numpy.array([[-34.54*(s + 0.0572), 1.913], [-30.22*s, -9.188*(s + 6.95e-4)]]) ... return G >>> rga_plot(G, axlim=[None, None, 0., 1.], w_start=-5, w_end=2) Note ---- This entry draws on and improves RGA.py. If accepted, then RGA.py could be removed from the repository ''' if axlim is None: axlim = [None, None, None, None] w = numpy.logspace(w_start, w_end, points) s = w * 1j dim = numpy.shape( G(0)) # Number of rows and columns in SS transfer function freqresp = map(G, s) count = 0 # Arrange the individual RGA responses to be compatible with the plotting order of plt.subplot rga = numpy.zeros([dim[0] * dim[1], points]) for i in range(dim[0]): for k in range(dim[1]): rga[count, :] = numpy.array( numpy.abs(([utils.RGA(Gfr)[i, k] for Gfr in freqresp]))) count += 1 plt.figure('RGA') plt.clf() plt.gcf().set_facecolor('white') plot_No = 1 for i in range(dim[0]): for k in range(dim[1]): plt.subplot(dim[0], dim[1], plot_No) plt.semilogx(w, rga[plot_No - 1]) plot_No += 1 plt.ylabel('|$\lambda$$_{ %s, %s}$|' % (i + 1, k + 1)) plt.axis(axlim) if i == dim[ 0] - 1: # To avoid clutter only plot xlabel on the very bottom subplots plt.xlabel('Frequency [rad/unit time]') plt.title('Output %s vs. input %s' % (i + 1, k + 1)) plt.show() return
def rga_nm_plot(G, pairing=None, axlim=None, w_start=-2, w_end=2, points=100): ''' Plots the RGA number for a specified pairing Parameters ---------- G : numpy array plant model pairing : sparse numpy array of the same shape as G An array of zeros with a 1. at each required output-input pairing The default is a diagonal pairing with 1.'s on the diagonal Returns ------- fig(RGA Number) : figure A figure of the RGA number for a specified pairing over a given frequency range Example ------- # Adapted from example 3.11 pg 86 S. Skogestad >>> def G(s): ... G = 0.01*numpy.exp(-5*s)/((s + 1.72e-4)*(4.32*s + 1))*numpy.array([[-34.54*(s + 0.0572), 1.913], [-30.22*s, -9.188*(s + 6.95e-4)]]) ... return G >>> pairing = numpy.array([[1., 0.], [0., 1.]]) >>> rga_nm_plot(G, pairing, axlim=[None, None, 0., 1.], w_start=-5, w_end=2) Note ---- This plotting function can only be used on square systems ''' if axlim is None: axlim = [None, None, None, None] w = numpy.logspace(w_start, w_end, points) s = w * 1j dim = numpy.shape( G(0)) # Number of rows and columns in SS transfer function freqresp = map(G, s) if pairing is None: # Setting a blank entry to the default of a diagonal comparison diag = numpy.identity(dim[0]) print('RGA number being calculated for a diagonal pairing') elif not all(pairing.shape == dim): print( 'RGA_Number_Plot on plots square n by n matrices, make sure input matrix is square' ) pass else: diag = pairing plt.figure('RGA Number') plt.clf() plt.gcf().set_facecolor('white') plt.semilogx( w, [numpy.sum(numpy.abs(utils.RGA(Gfr) - diag)) for Gfr in freqresp]) plt.axis(axlim) plt.ylabel('||$\Lambda$(G) - I||$_{sum}$', fontsize=15) plt.xlabel('Frequency (rad/unit time)') plt.show() return
def rga_plot(G, w_start=-2, w_end=2, axlim=None, points=1000, fig=0, plot_type='elements', input_label=None, output_label=None): """ Plots the relative gain interaction between each output and input pairing Parameters ---------- G : numpy matrix Plant model. plot_type : string Type of plot. ========= ============================ plot_type Type of plot ========= ============================ all All the RGAs on one plot output Plots grouped by output input Plots grouped by input element Each element has its own plot ========= ============================ Returns ------- Plot : matplotlib figure Example ------- Adapted from example 3.11 pg 86 S. Skogestad >>> def G(s): ... G = 0.01**(-5*s)/((s + 1.72e-4)*(4.32*s + 1))*numpy.matrix([[-34.54*(s + 0.0572), 1.913], [-30.22*s, -9.188*(s + 6.95e-4)]]) ... return G >>> rga_plot(G, w_start=-5, w_end=2, axlim=[None, None, 0., 1.]) """ s, w, axlim = df.frequency_plot_setup(axlim, w_start, w_end, points) dim = G(0).shape # Number of rows and columns in SS transfer function freqresp = [G(si) for si in s] plot_No = 1 if (input_label is None) and (output_label is None): labels = False elif numpy.shape(input_label)[0] == numpy.shape(output_label)[0]: labels = True else: raise ValueError('Input and output label count is not equal') if plot_type == 'elements': fig = adjust_spine('Frequency [rad/unit time]', 'RGA magnitude', -0.05, -0.03, 0.8, 0.9) for i in range(dim[0]): for j in range(dim[1]): ax = fig.add_subplot(dim[0], dim[1], plot_No) if labels: ax.set_title('Output (%s) vs. Input (%s)' % (output_label[i], input_label[j])) else: ax.set_title('Output %s vs. Input %s' % (i + 1, j + 1)) ax.semilogx( w, numpy.array( numpy.abs( ([utils.RGA(Gfr)[i, j] for Gfr in freqresp])))) plot_No += 1 ax.axis(axlim) ax.set_ylabel('$|\lambda$$_{%s, %s}|$' % (i + 1, j + 1)) box = ax.get_position() ax.set_position( [box.x0, box.y0, box.width * 0.8, box.height * 0.9]) elif plot_type == 'outputs': # i fig = adjust_spine('Frequency [rad/unit time]', 'RGA magnitude', -0.05, -0.03, 1, 0.9) for i in range(dim[0]): ax = fig.add_subplot(dim[1], 1, plot_No) ax.set_title('Output %s vs. input j' % (i + 1)) rgamax = [] for j in range(dim[1]): rgas = numpy.array( numpy.abs(([utils.RGA(Gfr)[i, j] for Gfr in freqresp]))) ax.semilogx(w, rgas, label='$\lambda$$_{%s, %s}$' % (i + 1, j + 1)) rgamax.append(max(rgas)) if j == dim[1] - 1: # self-scaling algorithm if axlim is not None: ax.axis(axlim) else: ax.axis([None, None, None, max(rgamax)]) ax.set_ylabel('$|\lambda$$_{%s, j}|$' % (i + 1)) box = ax.get_position() ax.set_position([box.x0, box.y0, box.width, box.height * 0.9]) ax.legend() plot_No += 1 elif plot_type == 'inputs': # j fig = adjust_spine('Frequency [rad/unit time]', 'RGA magnitude', -0.05, -0.03, 1, 0.9) for j in range(dim[1]): ax = fig.add_subplot(dim[0], 1, plot_No) ax.set_title('Output i vs. input %s' % (j + 1)) rgamax = [] for i in range(dim[0]): rgas = numpy.array( numpy.abs(([utils.RGA(Gfr)[i, j] for Gfr in freqresp]))) ax.semilogx(w, rgas, label='$\lambda$$_{%s, %s}$' % (i + 1, j + 1)) rgamax.append(max(rgas)) if i == dim[1] - 1: # self-scaling algorithm if axlim is not None: ax.axis(axlim) else: ax.axis([None, None, None, max(rgamax)]) ax.set_ylabel('$|\lambda$$_{i, %s}|$' % (j + 1)) box = ax.get_position() ax.set_position([box.x0, box.y0, box.width, box.height * 0.9]) ax.legend() plot_No += 1 elif plot_type == 'all': for i in range(dim[0]): for j in range(dim[1]): plt.semilogx( w, numpy.array( numpy.abs([utils.RGA(Gfr)[i, j] for Gfr in freqresp]))) plt.axis(axlim) plt.ylabel('|$\lambda$$_{i,j}$|') plt.xlabel('Frequency [rad/unit time]') else: raise ValueError("Invalid plot_type parameter.")